# Copyright 2020 Intel Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

CMAKE_MINIMUM_REQUIRED(VERSION 3.2 FATAL_ERROR)

PROJECT(avalon-enclave-bridge C CXX)

LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

SET (EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
SET (LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib)

SET(DEPS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/deps")
SET(TCF_TOP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../")
SET(TCF_CORE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../")

SET(ENCLAVE_TYPE "$ENV{ENCLAVE_TYPE}")
if("${ENCLAVE_TYPE} " STREQUAL " ")
    message(WARNING,
    "ENCLAVE_TYPE environment variable not defined, defaulting to Singleton enclave")
    SET(ENCLAVE_TYPE "singleton")
endif()

# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
# Configure Environment
# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

SET(SGX_MODE "$ENV{SGX_MODE}")
if("${SGX_MODE} " STREQUAL " ")
    SET(SGX_MODE "SIM")
    message(STATUS "Setting default SGX_MODE=${SGX_MODE}")
endif()
IF("${SGX_MODE}" STREQUAL "SIM")
    OPTION(SGX_USE_SIMULATOR "Use the Intel SGX simulator" TRUE)
ELSE()
    OPTION(SGX_USE_SIMULATOR "Use the Intel SGX simulator" FALSE)
ENDIF()

SET(SGX_SDK "$ENV{SGX_SDK}")
if("${SGX_SDK} " STREQUAL " ")
    message(FATAL_ERROR "SGX_SDK environment variable not defined!")
endif()
SET(SGX_SSL "$ENV{SGX_SSL}")
if("${SGX_SSL} " STREQUAL " ")
    SET(SGX_SSL "/opt/intel/sgxssl")
    message(STATUS "Setting default SGX_SSL=${SGX_SSL}")
endif()

# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
# ADDITIONAL LIBRARIES
# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

# Intel SGX edger is a utility that generates edl artifacts
SET(SGX_EDGER "${SGX_SDK}/bin/x64/sgx_edger8r")
SET(SGX_INCLUDE "${SGX_SDK}/include")
SET(SGX_SSL_INCLUDE "${SGX_SSL}/include")

# This library is needed to build edl artifacts
SET(SGX_LIBS_UNTRUSTED_NAMES sgx_usgxssl)

SET(SGX_LIBS_UNTRUSTED_NAMES ${SGX_LIBS_UNTRUSTED_NAMES} pthread)

IF(${SGX_USE_SIMULATOR})
    ADD_DEFINITIONS(-D SGX_SIMULATOR)
    SET(SGX_LIBS_UNTRUSTED_NAMES sgx_urts_sim sgx_epid_sim ${SGX_LIBS_UNTRUSTED_NAMES})
ELSE()
    SET(SGX_LIBS_UNTRUSTED_NAMES sgx_urts sgx_epid ${SGX_LIBS_UNTRUSTED_NAMES})
ENDIF()

FOREACH(lib ${SGX_LIBS_UNTRUSTED_NAMES})
    SET(${lib} ${lib})
ENDFOREACH(lib)

FOREACH(lib ${SGX_LIBS_UNTRUSTED_NAMES})
    SET(SGX_LIBS_UNTRUSTED ${SGX_LIBS_UNTRUSTED} ${${lib}})
ENDFOREACH(lib)

# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
FUNCTION(SGX_EDGE_UNTRUSTED EDL EDL_PATH EDGE_FILES)
    GET_FILENAME_COMPONENT(EDL_BASE_NAME ${EDL} NAME_WE)
    GET_FILENAME_COMPONENT(EDL_DIR_NAME ${EDL} DIRECTORY)
    INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})

    SET (EDGE_FILES_LIST "${CMAKE_CURRENT_BINARY_DIR}/${EDL_BASE_NAME}_u.h"
        "${CMAKE_CURRENT_BINARY_DIR}/${EDL_BASE_NAME}_u.c")
    SET (${EDGE_FILES} ${EDGE_FILES_LIST} PARENT_SCOPE)
    ADD_CUSTOM_COMMAND( OUTPUT ${EDGE_FILES_LIST}
        COMMAND "${SGX_EDGER}" --untrusted ${EDL} --search-path ${EDL_PATH}
	    --search-path ${SGX_INCLUDE}
        --search-path ${SGX_SSL_INCLUDE} --search-path ${EDL_DIR_NAME}
        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
        DEPENDS ${EDL}
    )
ENDFUNCTION()

FUNCTION(LINK_ENCLAVE_BRIDGE_COMMON_LIBRARIES)
    TARGET_LINK_LIBRARIES(${PROJECT_NAME} PRIVATE ${SGX_LIBS_UNTRUSTED})
    TARGET_LINK_LIBRARIES(${PROJECT_NAME} PRIVATE -luavalon-common -luavalon-crypto
        -luavalon-base64 -luavalon-sgx-common -lpthread)
ENDFUNCTION()

FUNCTION(INCLUDE_ENCLAVE_BRIDGE_COMMON_DIRECTORIES)
    INCLUDE_DIRECTORIES(${SGX_INCLUDE})
    INCLUDE_DIRECTORIES(${TCF_TOP_DIR}/common/cpp)
    INCLUDE_DIRECTORIES(${TCF_CORE_DIR}/trusted_worker_manager/common)
    INCLUDE_DIRECTORIES(${TCF_TOP_DIR}/common/cpp/crypto)
    INCLUDE_DIRECTORIES(${TCF_TOP_DIR}/common/cpp/packages/base64)
    INCLUDE_DIRECTORIES(${TCF_CORE_DIR}/trusted_worker_manager/enclave_untrusted/enclave_bridge)
ENDFUNCTION()

# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m64")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-attributes")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m64")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -O2")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} \
-Wl,-L,${TCF_TOP_DIR}/common/cpp/build")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} \
-Wl,-L,${TCF_CORE_DIR}/trusted_worker_manager/common/build")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-L,$ENV{SGX_SDK}/lib64")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-L,$ENV{SGX_SSL}/lib64")

IF(${ENCLAVE_TYPE} STREQUAL "singleton")
    ADD_DEFINITIONS(-DBUILD_SINGLETON=1)
    ADD_SUBDIRECTORY(singleton)
ELSEIF(${ENCLAVE_TYPE} STREQUAL "kme")
    ADD_DEFINITIONS(-DBUILD_KME=1)
    ADD_SUBDIRECTORY(kme)
ELSEIF(${ENCLAVE_TYPE} STREQUAL "wpe")
    ADD_DEFINITIONS(-DBUILD_WPE=1)
    ADD_SUBDIRECTORY(wpe)
ELSE()
    MESSAGE(FATAL_ERROR, "Unknown enclave build argument")
ENDIF()
